<?php
namespace App\Controllers\Admin\System;

use App\Components\Admin\Paginator;
use App\Components\Admin\ResponseHelper;
use App\Components\Twig\Twig;
use App\Models\System\SystemRole;
use App\Models\System\SystemRoleUser;
use App\Models\System\SystemUser;
use Exception;
use Illuminate\Support\Facades\DB;
use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;

/**
 * 系统管理员
 */
class UserController
{
    /**
     * 系统用户列表
     * @auth
     * @menu
     */
    public function index(Request $request, Response $response)
    {
        $params = $request->getQueryParams();
        $params = array_filter($params);

        $listRs = SystemUser::orderBy('id', 'desc');
        if (isset($params['nickname'])) {
            $listRs = $listRs->where('nickname', 'like', '%' . $params['nickname'] . '%');
        }
        if (isset($params['status']) && in_array($params['status'], [1, 2])) {
            $listRs = $listRs->where('status', $params['status']);
        }
        if (isset($params['logged_at'])) {
            $params['logged_at'] = explode(' - ', $params['logged_at']);
            if (isset($params['logged_at'][1]) && !isset($params['logged_at'][2])) {
                $params['logged_at'][0] = strtotime($params['logged_at'][0]);
                $params['logged_at'][1] = strtotime($params['logged_at'][1]);
                if ($params['logged_at'][0] !== false && $params['logged_at'][1] !== false) {
                    $params['logged_at'][0] = date('Y-m-d', $params['logged_at'][0]);
                    $params['logged_at'][1] = date('Y-m-d', $params['logged_at'][1]);
                    $listRs = $listRs->where('logged_at', '>=', $params['logged_at'][0])
                        ->where('logged_at', '<=', $params['logged_at'][1]);
                    $params['logged_at'] = implode(' - ', $params['logged_at']);
                } else {
                    unset($params['logged_at']);
                }
            } else {
                unset($params['logged_at']);
            }
        }
        if (isset($params['created_at'])) {
            $params['created_at'] = explode(' - ', $params['created_at']);
            if (isset($params['created_at'][1]) && !isset($params['created_at'][2])) {
                $params['created_at'][0] = strtotime($params['created_at'][0]);
                $params['created_at'][1] = strtotime($params['created_at'][1]);
                if ($params['created_at'][0] !== false && $params['created_at'][1] !== false) {
                    $params['created_at'][0] = date('Y-m-d', $params['created_at'][0]);
                    $params['created_at'][1] = date('Y-m-d', $params['created_at'][1]);
                    $listRs = $listRs->where('created_at', '>=', $params['created_at'][0])
                        ->where('created_at', '<=', $params['created_at'][1]);
                    $params['created_at'] = implode(' - ', $params['created_at']);
                } else {
                    unset($params['created_at']);
                }
            } else {
                unset($params['created_at']);
            }
        }
        $listRs = Paginator::paginate($listRs, $params);

        $userIds = array_column($listRs['data'], 'id');
        if (isset($userIds[0])) {
            $userRoleRs = SystemRoleUser::select('id', 'role_id', 'user_id')
                ->whereIn('user_id', $userIds)->get()->toArray();
            $roleIds = array_column($userRoleRs, 'role_id');
            $roleIds = array_values(array_unique($roleIds));
            if (isset($roleIds[0])) {
                $roleRs = SystemRole::select('id', 'title')
                    ->whereIn('id', $roleIds)->get()->toArray();
                foreach ($listRs['data'] as $k1 => $v1) {
                    $userRole = [];
                    foreach ($userRoleRs as $v2) {
                        if ($v1['id'] != $v2['user_id']) {
                            continue;
                        }
                        foreach ($roleRs as $v3) {
                            if ($v2['role_id'] != $v3['id']) {
                                continue;
                            }
                            $userRole[] = $v3['title'];
                        }
                    }
                    $listRs['data'][$k1]['role'] = $userRole;
                }
            }

            foreach ($listRs['data'] as $k => $v) {
                $listRs['data'][$k]['created_at'] = date('Y-m-d H:i:s', strtotime($v['created_at']));
                if (isset($v['logged_at'])) {
                    $listRs['data'][$k]['logged_at'] = date('Y-m-d H:i:s', strtotime($v['logged_at']));
                }
            }
        }

        $view = Twig::fromRequest($request);
        $response->getBody()->write($view->fetch('admin/system/user/index.html', [
            'title' => '系统管理员列表',
            'list' => $listRs,
            'params' => $params,
        ]));
        return $response;
    }

    /**
     * 编辑系统用户
     * @auth
     */
    public function edit(Request $request, Response $response)
    {
        $roleRs = SystemRole::select('id', 'title')
            ->where('status', 1)
            ->orderBy('id', 'asc')->get()->toArray();

        if ($request->getMethod() == 'POST') {
            $params = $request->getParsedBody();
            $params = array_filter($params);
            if (isset($params['id']) && $params['id'] > 0) {
                !isset($params['password']) && $params['password'] = '';
            } else {
                if (!isset($params['username'])) {
                    return ResponseHelper::error($response, '请输入登录账号');
                }
                if (strlen($params['username']) > 30) {
                    return ResponseHelper::error($response, '登录账号不能超出30个字符');
                }

                if (!isset($params['password'])) {
                    return ResponseHelper::error($response, '请输入登录密码');
                }
            }
            !isset($params['nickname']) && $params['nickname'] = '';
            if (isset($params['role'])) {
                $roleIds = array_column($roleRs, 'id');
                foreach ($params['role'] as $v) {
                    if (!in_array($v, $roleIds)) {
                        return ResponseHelper::error($response, '权限组ID:' . $v . ' 错误');
                    }
                }
            }

            $repeatRs = SystemUser::select('id')
                ->where('username', $params['username'])->get()->toArray();
            if (isset($params['id']) && $params['id'] > 0) {
                if (isset($repeatRs[0]['id']) && $repeatRs[0]['id'] != $params['id']) {
                    return ResponseHelper::error($response, '登录账号已存在，不能重复');
                }
            } else {
                if (isset($repeatRs[0]['id'])) {
                    return ResponseHelper::error($response, '登录账号已存在，不能重复');
                }
            }

            DB::beginTransaction();
            try {
                if (isset($params['id']) && $params['id'] > 0) {
                    $user = SystemUser::find($params['id']);
                    if (!isset($user->id)) {
                        throw new Exception('参数ID错误');
                    }
                    if ($user->username != $params['username']) {
                        $user->username = $params['username'];
                    }
                    if ($user->nickname != $params['nickname']) {
                        $user->nickname = $params['nickname'];
                    }
                    if ($params['password'] != '') {
                        $user->password = password_hash($params['password'], PASSWORD_DEFAULT);
                    }
                    $user->save();

                    $userRoleRs = SystemRoleUser::select('id', 'role_id', 'deleted_at')
                        ->where('user_id', $user->id)
                        ->withTrashed()
                        ->orderBy('id', 'asc')->get()->toArray();
                    foreach ($userRoleRs as $v) {
                        if (in_array($v['role_id'], $params['role'])) {
                            if (isset($v['deleted_at'])) {
                                $updateRs = SystemRoleUser::where('id', $v['id'])
                                    ->where('user_id', $user->id)->restore();
                                if ($updateRs != 1) {
                                    throw new Exception('用户权限组恢复错误');
                                }
                            }
                        } else {
                            if (isset($v['deleted_at'])) {
                            } else {
                                $deleteRs = SystemRoleUser::where('id', $v['id'])
                                    ->where('user_id', $user->id)->delete();
                                if ($deleteRs != 1) {
                                    throw new Exception('用户权限组删除错误');
                                }
                            }
                        }
                    }
                    $userRoleIds = array_column($userRoleRs, 'role_id');
                } else {
                    $user = new SystemUser;
                    $user->username = $params['username'];
                    $user->nickname = $params['nickname'];
                    $user->password = password_hash($params['password'], PASSWORD_DEFAULT);
                    $user->status = 1;
                    $user->save();
                    if (!isset($user->id) || $user->id <= 0) {
                        throw new Exception('用户增加错误');
                    }

                    $userRoleIds = [];
                }

                foreach ($params['role'] as $v) {
                    if (in_array($v, $userRoleIds)) {
                        continue;
                    }

                    $userRole = new SystemRoleUser;
                    $userRole->role_id = $v;
                    $userRole->user_id = $user->id;
                    $userRole->save();
                    if (!isset($userRole->id) || $userRole->id <= 0) {
                        throw new Exception('用户权限组增加错误');
                    }
                }

                DB::commit();
            } catch (Exception $e) {
                DB::rollBack();

                return ResponseHelper::error($response, $e->getMessage());
            }

            SystemRoleUser::clearUserRoleCache($user->id);

            return ResponseHelper::success($response);
        }

        $params = $request->getQueryParams();
        $params = array_filter($params);
        if (isset($params['id']) && $params['id'] > 0) {
            $infoRs = SystemUser::where('id', $params['id'])->first();
            if (!isset($infoRs->id)) {
                throw new Exception('管理员未找到');
            }
            $infoRs = $infoRs->toArray();

            $userRoleRs = SystemRoleUser::select('id', 'role_id')
                ->where('user_id', $infoRs['id'])
                ->orderBy('id', 'asc')->get()->toArray();
            $userRoleRs = array_column($userRoleRs, 'role_id');
            foreach ($roleRs as $k => $v) {
                if (in_array($v['id'], $userRoleRs)) {
                    $roleRs[$k]['own'] = true;
                } else {
                    $roleRs[$k]['own'] = false;
                }
            }

            $title = '编辑管理员信息';
        } else {
            $title = '新增管理员';
        }

        $view = Twig::fromRequest($request);
        $response->getBody()->write($view->fetch('admin/system/user/edit.html', [
            'title' => $title,
            'info' => $infoRs ?? [],
            'role' => $roleRs,
        ]));
        return $response;
    }

    /**
     * 系统用户状态
     * @auth
     */
    public function state(Request $request, Response $response)
    {
        if ($request->getMethod() == 'POST') {
            $params = $request->getParsedBody();
            if (!isset($params['id']) || $params['id'] <= 0) {
                return ResponseHelper::error($response, '参数ID错误');
            }
            if (isset($params['action']) && $params['action'] == 'status') {
                if (!isset($params['status']) || !in_array($params['status'], ['true', 'false'])) {
                    return ResponseHelper::error($response, '参数STATUS错误');
                }
                $updateData = ['status' => $params['status'] == 'true' ? 1 : 2];
                $updateRs = SystemUser::where('id', $params['id'])
                    ->update($updateData);
                if ($updateRs != 1) {
                    return ResponseHelper::error($response, '更新错误');
                }
                return ResponseHelper::success($response);
            } else {
                return ResponseHelper::error($response, '参数ACTION错误');
            }
        }
    }
}
